package com.xj.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @Description: 字符串工具类
 * @Author: Chuanlei.Sun
 * @Date: Created in 2018/10/28 22:11
 */
@Slf4j
public final class StringUtils extends org.apache.commons.lang3.StringUtils {

    // 逗号字符串常量
    public static final String COMMA = ",";
    // 冒号字符串常量
    public static final String COLON = ":";
    // 编码格式UTF-8
    public static final String UTF_8 = "UTF-8";
    // 空字符串
    public static final String EMPTY = "";

	private final static BigDecimal FIFTEEN=new BigDecimal(15);
	private final static BigDecimal FIFTY=new BigDecimal(50);

    /**
     * 用splitStr分割str字符串得到的字符串数组，判断searchStr是否在该数组中，不区分大小写
     *
     * @param str       源字符串
     * @param searchStr 要寻找的字符串
     * @param splitStr  分割字符串
     * @return boolean
     * @author Chuanlei.Sun
     * @date 2018/10/28 22:21
     */
    public static boolean contains(String str, String searchStr, String splitStr) {
        if (str == null || searchStr == null) {
            return false;
        }
        if (str.equalsIgnoreCase(searchStr)) {
            return true;
        }
        boolean result = false;
        String[] strs = str.split(splitStr);
        for (String s : strs) {
            if (searchStr.equalsIgnoreCase(s)) {
                result = true;
                break;
            }
        }
        return result;
    }

	/**
	 * 用splitStr分割str字符串得到的字符串数组，判断searchStr是否包含数据中任意元素，不区分大小写
	 * @param str       源字符串
	 * @param searchStr 要寻找的字符串
	 * @param splitStr  分割字符串
	 * @return boolean
	 * @author Chuanlei.Sun
	 * @date 2018/10/28 22:21
	 */
	public static boolean containsAny(String str, String searchStr, String splitStr) {
		if (str == null || searchStr == null) {
			return false;
		}
		if (str.equalsIgnoreCase(searchStr)) {
			return true;
		}
		boolean result = false;
		String[] strs = str.split(splitStr);
		for (String s : strs) {
			if (searchStr.indexOf(s) > 0) {
				result = true;
				break;
			}
		}
		return result;
	}

    /**
     * 使用指定字符，拆分字符串为字符串集合
     *
     * @param str    源字符串
     * @param symbol 指定字符
     * @return java.util.List<java.lang.String>
     * @author Chuanlei.Sun
     * @date 2018/10/28 22:23
     */
    public static List<String> splitBySymbol(String str, String symbol) {
        if (isBlank(str) || isBlank(symbol)) {
            return null;
        }
        return Arrays.stream(str.trim().split(symbol)).collect(Collectors.toList());
    }

    /**
     * 使用指定字符，合并字符串集合为字符串
     *
     * @param strs   源字符串集合
     * @param symbol 指定字符
     * @return java.lang.String
     * @author Chuanlei.Sun
     * @date 2018/10/28 22:23
     */
    public static String mergeBySymbol(List<String> strs, String symbol) {
        if (CollectionUtils.isEmpty(strs) || isBlank(symbol)) {
            return null;
        }
        return String.join(symbol, strs);
    }

    /**
     * 获取指定位数的随机数
     *
     * @param digit 指定位数
     * @return java.lang.String
     * @author Chuanlei.Sun
     * @date 2018/10/28 23:22
     */
    public static String random(int digit) {
        Random random = new Random();
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < digit; i++) {
            result.append(random.nextInt(10));
        }
        return result.toString();
    }

    /**
     * 获取机器码
     *
     * @author Chuanlei.Sun
     * @date 2018/10/28 23:27
     */
    public static String getMachineCode() {
        String result = "";
        try {
            long start = System.currentTimeMillis();
            Process process = Runtime.getRuntime().exec(new String[]{"wmic", "cpu", "get", "ProcessorId"});
            process.getOutputStream().close();
            Scanner sc = new Scanner(process.getInputStream());
            String property = sc.next();
            String serial = sc.next();
            log.trace("{}:{}", property, serial);
            log.trace("耗时:{}", System.currentTimeMillis() - start);
            return MD5Utils.encode(serial);
        } catch (IOException e) {
            log.error("ERROR getMachineCode message:", e);
        }
        return result;
    }

    /**
     * 根据指定字符串长度，获取指定长度的字符串长度字符串
     * 当字符串长度的长度不满足指定长度时，左边补0
     *
     * @param str       指定字符串
     * @param lengthStr 指定长度
     * @return java.lang.String
     * @author Chuanlei.Sun
     * @date 2018/11/14 21:43
     */
    public static String leftAddZero(String str, int lengthStr) {
        int lengthNum = 0;
        try {
            lengthNum = str.getBytes("gbk").length;
        } catch (UnsupportedEncodingException e) {
            log.error(">>>>>>>>> ERROR 获取字符串字节长度异常:", e);
        }
        return String.format("%0" + lengthStr + "d", lengthNum);
    }

    /**
     * 生成流水单号
     * 自定义位数单号前缀 + 14位时间戳 + 自定义位数随机数
     *
     * @param typePrefix   单据类型前缀
     * @param randomLength 随机数长度
     * @return java.lang.String
     * @author Chuanlei.Sun
     * @date 2018/11/21 10:01
     */
    public static synchronized String createFlowNo(String typePrefix, int randomLength) {
        return (StringUtils.isBlank(typePrefix) ? "" : typePrefix) + DateUtils.formatDate(DateUtils.yyyyMMddHHmmss) + random(Math.abs(randomLength));
    }

    /**
     * 替换源字符串中第一个指定字符串
     *
     * @param str       源字符串
     * @param sourceStr 指定要替换字符串
     * @param targetStr 指定目标字符串
     * @return java.lang.String
     * @author Chuanlei.Sun
     * @date 2018/11/23 20:49
     */
    public static String replaceFirst(String str, String sourceStr, String targetStr) {
        return replace(str, sourceStr, targetStr, 1);
    }

    /**
     * 替换源字符串中最后一个指定字符串
     *
     * @param str       源字符串
     * @param sourceStr 指定要替换字符串
     * @param targetStr 指定目标字符串
     * @return java.lang.String
     * @author Chuanlei.Sun
     * @date 2018/11/23 20:49
     */
    public static String replaceLast(String str, String sourceStr, String targetStr) {
        if (isAnyBlank(str, sourceStr)) {
            return str;
        }
        int index = lastIndexOf(str, sourceStr);
        if (index < 0) {
            return str;
        }
        return substring(str, 0, index) + (null == targetStr ? "" : targetStr) + substring(str, index + sourceStr.length(), str.length());
    }

    /**
     * 移除源字符串中第一个指定字符串
     *
     * @param str    源字符串
     * @param remove 指定字符串
     * @return java.lang.String
     * @author Chuanlei.Sun
     * @date 2018/11/23 20:49
     */
    public static String deleteFirst(String str, String remove) {
        return replace(str, remove, "", 1);
    }

    /**
     * 移除源字符串中最后一个指定字符串
     *
     * @param str    源字符串
     * @param remove 指定字符串
     * @return java.lang.String
     * @author Chuanlei.Sun
     * @date 2018/11/23 20:49
     */
    public static String deleteLast(String str, String remove) {
        if (isAnyBlank(str, remove)) {
            return str;
        }
        int index = lastIndexOf(str, remove);
        if (index < 0) {
            return str;
        }
        return substring(str, 0, index) + substring(str, index + remove.length(), str.length());
    }

    /**
     * 若干字符串拼接
     * 若含null值,置为""
     *
     * @param strs 字符串
     * @return java.lang.String
     * @author Chuanlei.Sun
     * @date 2019/5/16 10:57
     */
    public static String concatStr(String... strs) {
        StringBuilder result = new StringBuilder(EMPTY);
        if (null != strs && strs.length > 0) {
            for (String str : strs) {
                result.append(StringUtils.isBlank(str) ? "" : str);
            }
        }
        return result.toString();
    }

    /**
     * 根据字节长度截取字符串
     * 判断传进来的字符串，是否大于指定的字节，如果大于递归调用，直到小于指定字节数 ，一定要指定字符编码，因为各个系统字符编码都不一样，字节数也不一样
     *
     * @param s   源字符串
     * @param num 指定的字节数
     * @return java.lang.String
     * @author Chuanlei.Sun
     * @date 2019-07-15 15:15
     */
    public static String subStringByByteUtf(String s, int num) throws Exception {
        int byteLen = s.getBytes(UTF_8).length;
        if (byteLen > num) {
            s = s.substring(0, s.length() - 1);
            s = subStringByByteUtf(s, num);
        }
        return s;
    }

	/**
	 * 产生一个三位随机数
	 * @return
	 */
	public static String seed(){
	    return String.valueOf(RandomUtils.nextInt(100, 999));
    }




	/**
	 * 字符串转数字计算乘积
	 * @param str1
	 * @param str2
	 * @return
	 */
	public static String multiply(String str1,String str2){
		BigDecimal a = new BigDecimal(str1);
		BigDecimal b = new BigDecimal(str2);
		b = a.multiply(b);
		return b.setScale(2,BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString();
	}

	/**
	 *  字符串转数字计算divide
	 * @param str1
	 * @param str2
	 * @return
	 */
	public static String divide(String str1,String str2){
		BigDecimal a = new BigDecimal(str1);
		BigDecimal b = new BigDecimal(str2);
		b = a.divide(b,2,BigDecimal.ROUND_HALF_UP);
		return b.stripTrailingZeros().toPlainString();
	}

	public static String add(String str1,String str2){
		BigDecimal a = new BigDecimal(str1);
		BigDecimal b = new BigDecimal(str2);
		b = a.add(b);
		return b.stripTrailingZeros().toPlainString();
	}

	/**
	 * 从规则计算箱装数
	 * 例如：1件*12组*2罐==> 24
	 * @param spec
	 * @param reg
	 * @return
	 */
	public static String getUnitRateFromSpec(String spec,String reg,String splitChar){
		if(StringUtils.isBlank(spec)){
			return "";
		}
		spec = regex(spec,reg);
		if(StringUtils.isBlank(spec)){
			return "";
		}
		String[] rates = spec.split(splitChar);
		BigDecimal rate = BigDecimal.ONE;
		for(String s: rates) {
			if (StringUtils.isNotBlank(s)) {
				rate = rate.multiply(new BigDecimal(s));
			}
		}
		return rate.stripTrailingZeros().toPlainString();
	}

	/**
	 * 单价处理
	 * 规则：原单价小于15，取原单价；原单价大于15，小于等于50，取单价除以10；原单价大于50的，取单价除以箱规；
	 * @param price
	 * @param prodSpec
	 * @return
	 */
	public static String priceAdjust(String price,String prodSpec,String prodSpecSplitChar){
		BigDecimal oldPrice = new BigDecimal(price);
		//原单价大于50的
		if(FIFTY.compareTo(oldPrice) < 0 ){
			if(StringUtils.isBlank(prodSpec)){
				return price;
			}
			String[] spec = prodSpec.split(prodSpecSplitChar);
			BigDecimal unit=BigDecimal.ONE;
			for(String s : spec){
				unit = unit.multiply(new BigDecimal(s));
			}
			return StringUtils.divide(price,unit.toPlainString());
		}
		// 原单价大于15，小于等于50
		else if(FIFTY.compareTo(oldPrice) >= 0 && FIFTEEN.compareTo(oldPrice) <= 0){
			return StringUtils.divide(price,BigDecimal.TEN.toPlainString());
		}else {
			return price;
		}
	}

	/**
	 * 获取总页数
	 * @param total
	 * @param pageSize
	 * @return
	 */
	public static int getTotalPages(int total,int pageSize){
		int pages = total / pageSize;
		if (total % pageSize > 0) {
			pages++;
		}
		return pages;
	}

	/**
	 * @param str 待匹配字符串
	 * @param reg 匹配正则表达式
	 * @return 匹配字符串
	 * @description 根据正则匹配规则匹配字符串
	 * @data 2020/7/27 15:22
	 */
	public static String regex(String str, String reg) {
		StringBuilder regexStr = new StringBuilder();
		Pattern pattern = Pattern.compile(reg);
		Matcher matcher = pattern.matcher(str);
		while (matcher.find()) {
			regexStr.append(matcher.group());
		}
		return regexStr.toString();
	}

	public static void main(String[] arg){
//		System.out.println(StringUtils.getUnitRateFromSpec("1件*21包","\\*"));
	//	System.out.println(regex("1件a*21包","[0-9*]{1,}"));
       String  str="256GB(6期免息)";
		String regex="\\(.*\\)";
		Pattern  pattern=Pattern.compile(regex);
		Matcher m = pattern.matcher(str);
		while (m.find()) {
			String  sss=m.group();
			System.out.println(sss);
		}
		if(str.matches(regex)){

		}
	}
}
